package imai78gae.heya.util;

import imai78gae.heya.exception.FileReadException;
import imai78gae.heya.exception.ParameterInvalidException;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

/**
 * テンプレートの操作処理を集約したユーティリティです。
 * 
 * @author imai78
 *
 */
public class TemplateUtil {

	/**
	 * 指定されたファイルを読み込んで、メールのテンプレートを返します。
	 * <p>
	 * テンプレートの内容は、１行ごとに改行コードを追加された１つの文字列として集計して返されます。
	 * </p>
	 * 
	 * @param templateFilePath メールのテンプレートが記述されたファイルのパス
	 * @return テンプレートの内容
	 */
	public static synchronized String getMailTemplate(String templateFilePath) {
		if (CheckUtil.isEmpty(templateFilePath)) {
			throw new ParameterInvalidException("templateFilePath is empty");
		}
		if (CheckUtil.isExistFile(templateFilePath) == false) {
			throw new ParameterInvalidException("templateFilePath is not found.>>>[" + templateFilePath + "]");
		}
		BufferedReader br = null;
		StringBuilder result = new StringBuilder();
		try {
			br = new BufferedReader(new FileReader(new File(templateFilePath)));
			String line = null;
			while ((line = br.readLine()) != null) {
				result.append(line).append("\n");
			}
		} catch (FileNotFoundException e) {
			throw new FileReadException(e);
		} catch (IOException e) {
			throw new FileReadException(e);
		} finally {
			if (br != null) {
				try {
					br.close();
				} catch (IOException e) {
					throw new FileReadException(e);
				}
			}
		}
		return result.toString();
	}

	/**
	 * 指定されたテンプレートの内容と{@code context}として渡されたパラメータを元に、実際の本文を作成して返します。
	 * 
	 * @param template テンプレートの内容
	 * @param context テンプレートに適用するパラメータ
	 * @return 作成した本文
	 */
	public static synchronized String createMessageBody(String template, Map<String, String> context) {
		if (CheckUtil.isEmpty(template)) {
			throw new ParameterInvalidException("template is empty.");
		}
		if (CheckUtil.isEmpty(context)) {
			throw new ParameterInvalidException("context is empty.");
		}
		String result = new String(template);
		Set<String> keyList = context.keySet();
		for (String key : keyList) {
			String replaceKey = createReplaceKey(key);
			result = result.replaceAll(replaceKey, context.get(key));
		}
		return result;
	}

	/**
	 * 渡された文字列からテンプレートの内容に記述された置換用キーワードを作成して返します。
	 * <p>
	 * ここで作成されたキーワードで、置換対象を検索します。
	 * </p>
	 * 
	 * @param key 置換用キーワードを作りたい文字列
	 * @return 置換用キーワード
	 */
	static synchronized String createReplaceKey(String key) {
		if (CheckUtil.isEmpty(key)) {
			throw new ParameterInvalidException("key is empty.");
		}
		return "\\{\\s\\$" + key + "\\s\\}";
	}

}
